package com.example.order.config;

import com.example.order.listener.OrderDelayListener;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

@Slf4j
@Configuration
@RequiredArgsConstructor
public class MqConfig {
    private final RabbitTemplate rabbitTemplate;

    @PostConstruct
    public void init() {
        rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback() {
            @Override
            public void returnedMessage(ReturnedMessage returned) {
                // 请注意！如果你使用了延迟队列插件，那么一定会调用该callback方法，因为数据并没有提交上去，
                // 而是提交在交换器中，过期时间到了才提交上去，并非是bug！你可以用if进行判断交换机名称来捕捉该报错
                // 获取你实际使用的延迟交换机名称，比如 MQConstants.DELAY_EXCHANGE_NAME
                String delayExchangeName = "order.delay.direct"; // 替换为实际的延迟交换机名称

                // 如果是延迟交换机的消息返回，则视为正常
                if (delayExchangeName.equals(returned.getExchange())) {
                    log.debug("延迟消息返回，正常现象 exchange: {}", returned.getExchange());
                    return;
                }
                log.error("触发return callback,");
                log.debug("exchange: {}", returned.getExchange());
                log.debug("routingKey:{}", returned.getRoutingKey());
                log.debug("message:{}", returned.getMessage());
                log.debug("replycode:{}", returned.getReplyCode());
                log.debug("replyText:{}", returned.getReplyText());
            }
        });


        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {
                if (ack) {
                    log.debug("消息发送成功 关联数据：({}),投递成功,确认情况：({}),原因：({})", correlationData, ack, cause);
                } else {
                    log.error("消息发送失败 关联数据：({}),投递失败,确认情况：({}),原因：({})", correlationData, ack, cause);
                }
            }
        });
    }
}
